<template>
  <Dialog v-model="dialogVisible" :title="dialogTitle" width="800px">
    <el-form
      ref="formRef"
      v-loading="formLoading"
      :model="formData"
      :rules="formRules"
      label-width="120px"
    >
      <el-row :gutter="16">
        <el-col :span="12">
          <el-form-item label="设备" prop="deviceId">
            <el-select
              v-model="formData.deviceId"
              class="!w-full"
              placeholder="请选择设备"
              filterable
              :loading="deviceLoading"
              @change="handleDeviceChange"
            >
              <el-option
                v-for="item in deviceOptions"
                :key="item.deviceId"
                :label="item.deviceName"
                :value="item.deviceId"
              >
                <div class="flex items-center">
                  <span>{{ item.deviceName }}</span>
                  <span class="text-gray-400 ml-2">({{ item.deviceId }})</span>
                </div>
              </el-option>
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="上报数据类型" prop="reportDataType">
            <el-select
              v-model="formData.reportDataType"
              class="!w-full"
              placeholder="请选择上报数据类型"
              @change="handleDataTypeChange"
            >
              <el-option
                v-for="item in reportDataTypeOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="当前标准值">
            <div class="flex items-center" v-if="standardValue !== null">
              <span>{{ standardValue }}</span>
              <span class="text-gray-400 ml-2">{{ getStandardValueUnit() }}</span>
            </div>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="上报数据实际值">
            <el-input-number
              v-model="formData.reportDataValue"
              :precision="2"
              :min="0"
              class="!w-full"
              placeholder="请输入上报数据实际值"
              @change="calculateReportDataLevel"
              @input="handleReportDataValueInput"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="上报数据级别" prop="reportDataLevel">
            <el-select
              v-model="formData.reportDataLevel"
              class="!w-full"
              placeholder="请选择上报数据级别"
              :disabled="autoCalculatedLevel"
            >
              <el-option
                v-for="item in reportDataLevelOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="上报数据时间" prop="reportDataTime">
            <el-date-picker
              v-model="formData.reportDataTime"
              type="datetime"
              class="!w-full"
              placeholder="请选择上报数据时间"
              value-format="YYYY-MM-DD HH:mm:ss"
              format="YYYY-MM-DD HH:mm:ss"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="累计能耗(kWh)">
            <el-input-number
              v-model="formData.energyConsumption"
              :precision="2"
              :min="0"
              class="!w-full"
              placeholder="请输入累计能耗(kWh)"
            />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="处理状态" prop="status">
            <el-select v-model="formData.status" class="!w-full" placeholder="请选择处理状态">
              <el-option
                v-for="item in reportStatusOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col :span="24">
          <el-form-item label="上报数据信息" prop="message">
            <el-input
              v-model="formData.message"
              type="textarea"
              :rows="3"
              placeholder="请输入上报数据信息"
            />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="submitForm">确定</el-button>
    </template>
  </Dialog>
</template>

<script lang="ts" setup>
import * as ReportApi from '@/api/energy/report'
import * as DeviceApi from '@/api/energy/device'
import {
  ReportDataVO,
  reportDataTypeOptions,
  reportDataLevelOptions,
  reportStatusOptions
} from '@/api/energy/report'
import { DeviceVO } from '@/api/energy/device'
import { useValidator } from '@/hooks/web/useValidator'
import { reactive, ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import Dialog from '@/components/Dialog/src/Dialog.vue'
import { cloneDeep } from 'lodash-es'
import dayjs from 'dayjs'

const { required } = useValidator()

const dialogVisible = ref(false)
const dialogTitle = ref('')
const formLoading = ref(false)
const formRef = ref()

// 设备选择相关
const deviceOptions = ref<DeviceVO[]>([])
const deviceLoading = ref(false)
const loadDevices = async () => {
  deviceLoading.value = true
  try {
    const res = await DeviceApi.getDeviceList()
    deviceOptions.value = res || []
  } catch (error) {
    console.error('获取设备列表失败', error)
  } finally {
    deviceLoading.value = false
  }
}

// 当前选中的设备
const currentDevice = ref<DeviceVO | null>(null)
const standardValue = ref<number | null>(null)
// 是否自动计算了数据级别
const autoCalculatedLevel = ref(false)

// 获取标准值单位
const getStandardValueUnit = () => {
  switch (formData.value.reportDataType) {
    case 'voltage':
      return 'V'
    case 'current':
      return 'A'
    case 'power':
      return 'kW'
    case 'temperature':
      return '℃'
    case 'energy_consumption':
      return 'kWh'
    default:
      return ''
  }
}

// 处理设备变更
const handleDeviceChange = (deviceId: string) => {
  // 清空数据类型和标准值
  formData.value.reportDataType = ''
  standardValue.value = null

  // 设置当前设备
  currentDevice.value = deviceOptions.value.find((device) => device.deviceId === deviceId) || null
}

// 处理数据类型变更
const handleDataTypeChange = (dataType: string) => {
  standardValue.value = null
  autoCalculatedLevel.value = false
  formData.value.reportDataLevel = ''

  if (!currentDevice.value || !dataType) {
    return
  }

  // 根据数据类型获取设备标准值
  switch (dataType) {
    case 'voltage':
      standardValue.value = Number(currentDevice.value.voltage)
      break
    case 'current':
      standardValue.value = Number(currentDevice.value.currents)
      break
    case 'power':
      standardValue.value = Number(currentDevice.value.activePower)
      break
    case 'temperature':
      standardValue.value = Number(currentDevice.value.temperature)
      break
    case 'energy_consumption':
      standardValue.value = Number(currentDevice.value.energyConsumption)
      break
  }

  // 如果已经有实际值，重新计算级别
  if (formData.value.reportDataValue) {
    calculateReportDataLevel()
  }
}

// 计算上报数据级别
const calculateReportDataLevel = () => {
  // 确保数据存在
  if (
    standardValue.value === null ||
    formData.value.reportDataValue === undefined ||
    formData.value.reportDataValue === null
  ) {
    return
  }

  // 确保转换为数值类型
  const standardVal = Number(standardValue.value)
  const actualValue = Number(formData.value.reportDataValue)

  // 检查转换后的值是否有效
  if (isNaN(standardVal) || isNaN(actualValue) || standardVal === 0) {
    return
  }

  // 如果实际值小于标准值，显示为正常级别
  if (actualValue <= standardVal) {
    formData.value.reportDataLevel = 'info'
    autoCalculatedLevel.value = true
    return
  }

  // 计算偏差百分比 = |实际值-标准值|/标准值 * 100%
  const deviation = (actualValue - standardVal) / standardVal

  // 根据偏差百分比确定数据级别
  if (deviation <= 0.1) {
    // 偏差在10%以内
    formData.value.reportDataLevel = 'info'
  } else if (deviation <= 0.2) {
    // 偏差在10%-20%之间
    formData.value.reportDataLevel = 'warning'
  } else {
    // 偏差超过20%
    formData.value.reportDataLevel = 'danger'
  }

  autoCalculatedLevel.value = true
}

// 处理上报数据实际值输入
const handleReportDataValueInput = (value: number | undefined) => {
  if (value !== undefined) {
    // 确保转换为数值
    formData.value.reportDataValue = Number(value)
  }
}

const defaultFormData: Partial<ReportDataVO> = {
  id: undefined,
  deviceId: '',
  reportDataType: '',
  reportDataValue: null as unknown as number,
  reportDataLevel: '',
  reportDataTime: undefined as unknown as string,
  energyConsumption: null as unknown as number,
  message: '',
  status: 'unprocessed',
  createTime: undefined as unknown as string
}

const formData = ref<Partial<ReportDataVO>>({ ...defaultFormData })

const formRules = reactive({
  deviceId: [required],
  reportDataType: [required],
  reportDataValue: [required],
  reportDataLevel: [required],
  reportDataTime: [required],
  energyConsumption: [required],
  status: [required]
})

const emit = defineEmits(['success'])

const open = async (type: string, id?: number) => {
  dialogVisible.value = true
  dialogTitle.value = type === 'create' ? '新增能耗报告数据' : '编辑能耗报告数据'
  formData.value = { ...defaultFormData }
  standardValue.value = null
  autoCalculatedLevel.value = false
  currentDevice.value = null

  // 设置默认的上报数据时间为当前时间
  if (type === 'create') {
    formData.value.reportDataTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  }

  // 加载设备列表
  await loadDevices()

  // 编辑
  if (id) {
    formLoading.value = true
    try {
      const res = await ReportApi.getReportData(id)
      // 确保reportDataValue是数值类型
      if (res.reportDataValue !== undefined && res.reportDataValue !== null) {
        res.reportDataValue = Number(res.reportDataValue)
      }

      // 确保reportDataTime正确格式化
      if (res.reportDataTime !== undefined && res.reportDataTime !== null) {
        if (typeof res.reportDataTime === 'number') {
          // 处理时间戳
          const timestamp =
            String(res.reportDataTime).length === 10
              ? Number(res.reportDataTime) * 1000
              : Number(res.reportDataTime)
          res.reportDataTime = dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')
        } else if (
          res.reportDataTime === '0' ||
          (typeof res.reportDataTime === 'string' && res.reportDataTime.includes('1970'))
        ) {
          // 处理无效日期
          res.reportDataTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
        }
      } else {
        // 如果为空，设置当前时间
        res.reportDataTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
      }

      formData.value = res

      // 设置当前设备
      if (res.deviceId) {
        currentDevice.value =
          deviceOptions.value.find((device) => device.deviceId === res.deviceId) || null

        // 如果有数据类型，获取标准值
        if (res.reportDataType && currentDevice.value) {
          handleDataTypeChange(res.reportDataType)
        }
      }
    } finally {
      formLoading.value = false
    }
  }
}

const submitForm = async () => {
  // 校验表单
  if (!formRef.value) return
  const valid = await formRef.value.validate()
  if (!valid) return

  // 提交请求
  formLoading.value = true
  try {
    // 克隆一份表单数据
    const reqData = cloneDeep(formData.value)

    // 确保reportDataValue是数值类型
    if (reqData.reportDataValue !== undefined && reqData.reportDataValue !== null) {
      reqData.reportDataValue = Number(reqData.reportDataValue)
    }

    // 确保energyConsumption是数值类型
    if (reqData.energyConsumption !== undefined && reqData.energyConsumption !== null) {
      reqData.energyConsumption = Number(reqData.energyConsumption)
    }

    // 确保reportDataTime是字符串格式
    if (!reqData.reportDataTime) {
      // 如果为空，默认设置为当前时间
      reqData.reportDataTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
    } else if (typeof reqData.reportDataTime === 'object') {
      reqData.reportDataTime = dayjs(reqData.reportDataTime).format('YYYY-MM-DD HH:mm:ss')
    }

    if (reqData.id) {
      await ReportApi.updateReportData(reqData as Omit<ReportDataVO, 'createTime'>)
      ElMessage.success('修改成功')
    } else {
      await ReportApi.createReportData(reqData as Omit<ReportDataVO, 'id' | 'createTime'>)
      ElMessage.success('新增成功')
    }
    dialogVisible.value = false
    emit('success')
  } finally {
    formLoading.value = false
  }
}

// 加载数据
onMounted(() => {
  loadDevices()
})

// 向外暴露方法
defineExpose({ open })
</script>
